import mongoose from 'mongoose';
import { SystemDAO } from '../dao/SystemDAO';
import { PermissionDAO } from '../dao/PermissionDAO';
import { ISystemDocument, SystemStatus, SystemType } from '../models/system';
import { IPermissionDocument } from '../models/permission';

/**
 * 系统注册数据接口
 */
export interface RegisterSystemData {
  systemName: string;
  systemCode: string;
  description?: string;
  systemType: SystemType;
  version: string;
  callbackUrl?: string;
  allowedOrigins?: string[];
  createdBy: mongoose.Types.ObjectId;
}

/**
 * 系统配置更新数据接口
 */
export interface UpdateSystemConfigData {
  name?: string;
  description?: string;
  version?: string;
  callbackUrl?: string;
  allowedOrigins?: string[];
}

/**
 * 权限注册数据接口
 */
export interface RegisterPermissionData {
  name: string;
  code: string;
  type: string;
  description?: string;
}

/**
 * 系统密钥生成结果接口
 */
export interface GenerateSecretResult {
  success: boolean;
  systemId: mongoose.Types.ObjectId;
  secretKey: string;
  generatedAt: Date;
}

/**
 * 权限注册结果接口
 */
export interface RegisterPermissionsResult {
  success: boolean;
  systemId: string;
  registeredCount: number;
  permissions: {
    id: string;
    name: string;
    code: string;
    type: string;
  }[];
}

/**
 * 权限同步结果接口
 */
export interface SyncPermissionsResult {
  syncedCount: number;
  createdCount: number;
  updatedCount: number;
  errors: string[];
}

/**
 * 系统服务类
 * 提供系统管理相关的业务逻辑
 */
export class SystemService {
  private systemDAO: SystemDAO;
  private permissionDAO: PermissionDAO;

  constructor() {
    this.systemDAO = new SystemDAO();
    this.permissionDAO = new PermissionDAO();
  }

  /**
   * 注册新系统
   * @param systemData 系统注册数据
   * @returns 注册的系统文档
   */
  async registerSystem(systemData: RegisterSystemData): Promise<ISystemDocument> {
    // 输入验证
    if (!systemData.systemName || systemData.systemName.trim() === '') {
      throw new Error('系统名称不能为空');
    }

    if (!systemData.systemCode || systemData.systemCode.trim() === '') {
      throw new Error('系统代码不能为空');
    }

    if (!Object.values(SystemType).includes(systemData.systemType)) {
      throw new Error('无效的系统类型');
    }

    if (!systemData.version || !/^\d+\.\d+\.\d+$/.test(systemData.version)) {
      throw new Error('版本号格式应为 x.y.z');
    }

    if (!mongoose.Types.ObjectId.isValid(systemData.createdBy)) {
      throw new Error('无效的创建者ID');
    }

    try {
      return await this.systemDAO.create(systemData);
    } catch (error) {
      throw error;
    }
  }

  /**
   * 更新系统配置
   * @param systemId 系统ID
   * @param updateData 更新数据
   * @param updatedBy 更新者ID
   * @returns 更新后的系统文档
   */
  async updateSystemConfig(
    systemId: string | mongoose.Types.ObjectId,
    updateData: UpdateSystemConfigData,
    updatedBy: mongoose.Types.ObjectId
  ): Promise<ISystemDocument> {
    // 输入验证
    if (!mongoose.Types.ObjectId.isValid(systemId)) {
      throw new Error('无效的系统ID');
    }

    if (!mongoose.Types.ObjectId.isValid(updatedBy)) {
      throw new Error('无效的更新者ID');
    }

    if (updateData.version && !/^\d+\.\d+\.\d+$/.test(updateData.version)) {
      throw new Error('版本号格式应为 x.y.z');
    }

    try {
      const result = await this.systemDAO.update(systemId, updateData, updatedBy);
      if (!result) {
        throw new Error('系统不存在');
      }
      return result;
    } catch (error) {
      throw error;
    }
  }

  /**
   * 更新系统状态
   * @param systemId 系统ID
   * @param status 新状态
   * @param updatedBy 更新者ID
   * @returns 更新后的系统文档
   */
  async updateSystemStatus(
    systemId: string | mongoose.Types.ObjectId,
    status: SystemStatus,
    updatedBy: mongoose.Types.ObjectId
  ): Promise<ISystemDocument> {
    // 输入验证
    if (!mongoose.Types.ObjectId.isValid(systemId)) {
      throw new Error('无效的系统ID');
    }

    if (!mongoose.Types.ObjectId.isValid(updatedBy)) {
      throw new Error('无效的更新者ID');
    }

    if (!Object.values(SystemStatus).includes(status)) {
      throw new Error('无效的系统状态');
    }

    try {
      return await this.systemDAO.updateStatus(systemId, status, updatedBy);
    } catch (error) {
      throw error;
    }
  }

  /**
   * 生成系统密钥
   * @param systemId 系统ID
   * @param updatedBy 更新者ID
   * @returns 生成密钥结果
   */
  async generateSystemSecret(
    systemId: string | mongoose.Types.ObjectId,
    updatedBy: mongoose.Types.ObjectId
  ): Promise<GenerateSecretResult> {
    // 输入验证
    if (!mongoose.Types.ObjectId.isValid(systemId)) {
      throw new Error('无效的系统ID');
    }

    if (!mongoose.Types.ObjectId.isValid(updatedBy)) {
      throw new Error('无效的更新者ID');
    }

    try {
      const updatedSystem = await this.systemDAO.regenerateSecret(systemId, updatedBy);
     return {
        success: true,
        systemId: updatedSystem._id as mongoose.Types.ObjectId,
        secretKey: updatedSystem.secretKey,
        generatedAt: new Date()
      };
    } catch (error) {
      throw error;
    }
  }

  /**
   * 注册系统权限
   * @param systemId 系统ID
   * @param permissions 权限列表
   * @param createdBy 创建者ID
   * @returns 注册结果
   */
  async registerSystemPermissions(
    systemId: string | mongoose.Types.ObjectId,
    permissions: RegisterPermissionData[],
    createdBy: mongoose.Types.ObjectId
  ): Promise<RegisterPermissionsResult> {
    // 输入验证
    if (!mongoose.Types.ObjectId.isValid(systemId)) {
      throw new Error('无效的系统ID');
    }

    if (!mongoose.Types.ObjectId.isValid(createdBy)) {
      throw new Error('无效的创建者ID');
    }

    if (!permissions || permissions.length === 0) {
      throw new Error('权限列表不能为空');
    }

    try {
      // 准备权限数据
      const permissionData = permissions.map(perm => ({
        ...perm,
        systemId: mongoose.Types.ObjectId.isValid(systemId) 
          ? new mongoose.Types.ObjectId(systemId) 
          : systemId as mongoose.Types.ObjectId,
        createdBy
      }));

      const result = await this.permissionDAO.batchCreate(permissionData);

      return {
        success: true,
        systemId: systemId.toString(),
        registeredCount: result.length,
        permissions: result.map(p => ({
          id: (p._id as mongoose.Types.ObjectId).toString(),
          name: p.name,
          code: p.code,
          type: p.type
        }))
      };
    } catch (error) {
      throw error;
    }
  }

  /**
   * 同步系统权限
   * @param systemId 系统ID
   * @param permissions 权限列表
   * @param updatedBy 更新者ID
   * @returns 同步结果
   */
  async syncSystemPermissions(
    systemId: string | mongoose.Types.ObjectId,
    permissions: RegisterPermissionData[],
    updatedBy: mongoose.Types.ObjectId
  ): Promise<SyncPermissionsResult> {
    // 输入验证
    if (!mongoose.Types.ObjectId.isValid(systemId)) {
      throw new Error('无效的系统ID');
    }

    if (!mongoose.Types.ObjectId.isValid(updatedBy)) {
      throw new Error('无效的更新者ID');
    }

    if (!permissions || permissions.length === 0) {
      throw new Error('权限列表不能为空');
    }

    try {
      // 获取现有权限
      const existingPermissions = await this.permissionDAO.findBySystemId(
        mongoose.Types.ObjectId.isValid(systemId) 
          ? new mongoose.Types.ObjectId(systemId) 
          : systemId as mongoose.Types.ObjectId
      );

      const existingCodes = new Set(existingPermissions.map(p => p.code));
      const newPermissions = permissions.filter(p => !existingCodes.has(p.code));
      const updatePermissions = permissions.filter(p => existingCodes.has(p.code));

      let createdCount = 0;
      let updatedCount = 0;
      const errors: string[] = [];

      // 创建新权限
      if (newPermissions.length > 0) {
        const permissionData = newPermissions.map(perm => ({
          ...perm,
          systemId: mongoose.Types.ObjectId.isValid(systemId) 
            ? new mongoose.Types.ObjectId(systemId) 
            : systemId as mongoose.Types.ObjectId,
          createdBy: updatedBy
        }));

        const createResult = await this.permissionDAO.batchCreate(permissionData);
        createdCount = createResult.length;
      }

      // 更新现有权限
      for (const perm of updatePermissions) {
        try {
          const existingPerm = existingPermissions.find(p => p.code === perm.code);
          if (existingPerm) {
            await this.permissionDAO.update((existingPerm._id as mongoose.Types.ObjectId).toString(), {
              name: perm.name,
              description: perm.description,
              type: perm.type
            });
            updatedCount++;
          }
        } catch (error) {
          errors.push(`更新权限 ${perm.code} 失败: ${error instanceof Error ? error.message : '未知错误'}`);
        }
      }

      return {
        syncedCount: createdCount + updatedCount,
        createdCount,
        updatedCount,
        errors
      };
    } catch (error) {
      throw error;
    }
  }
}

export default SystemService;